#ifndef __LAMBDANODE__

#define __LAMBDANODE__

#include"integernode.h"
#include"variablenode.h"
#include"programnode.h"

class ChoiceNode : public ExpressionNode {
	
	public:
		
	ExpressionNode * cond;
	ExpressionNode * iftrue;
	ExpressionNode * iffalse;
	
	ChoiceNode(ExpressionNode *, ExpressionNode *, ExpressionNode *);
	ChoiceNode(ChoiceNode const &);
	~ChoiceNode();
	
	ExpressionNode * eval(ProgramNode const &) const;
	bool isFreeVar(VariableNode const &) const;
	bool isBoundVar(VariableNode const &) const;
	ExpressionNode * subst(VariableNode const &, ExpressionNode const *);
	ProgramNode * defun() const;
	IntegerNode deint() const;
	
	ExpressionNode * copy() const;
	
	string toString() const;
};

class ApplicationNode : public ExpressionNode {
	
	public:
	
	ExpressionNode * left;
	ExpressionNode * right;
	
	ApplicationNode(ExpressionNode *, ExpressionNode *);
	ApplicationNode(ApplicationNode const &);
	~ApplicationNode();
	
	ExpressionNode * eval(ProgramNode const &) const;
	bool isFreeVar(VariableNode const &) const;
	bool isBoundVar(VariableNode const &) const;

	ExpressionNode * subst(VariableNode const &, ExpressionNode const *);
	ProgramNode * defun() const;
	IntegerNode deint() const;
	
	ExpressionNode * copy() const;
	
	string toString() const;
};

class FunctionNode : public ExpressionNode {
	
	public:
		
	VariableNode var;
	ExpressionNode * expr;
	
	FunctionNode(VariableNode const &, ExpressionNode *);
	FunctionNode(FunctionNode const &);
	~FunctionNode();
	
	ExpressionNode * eval(ProgramNode const &) const;
	bool isFreeVar(VariableNode const &) const;
	bool isBoundVar(VariableNode const &) const;
	ExpressionNode * subst(VariableNode const &, ExpressionNode const *);
	ProgramNode * defun() const;
	IntegerNode deint() const;
	
	ExpressionNode * copy() const;
	
	string toString() const;	
};

#endif
